package com.xiaozhen.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaozhen.common.core.constant.Constants;
import com.xiaozhen.common.core.domain.system.SysRole;
import com.xiaozhen.common.core.domain.system.SysRoleMenu;
import com.xiaozhen.common.core.domain.system.SysUserRole;
import com.xiaozhen.common.core.domain.system.queryParams.SysRoleQueryParam;
import com.xiaozhen.common.core.exception.CustomException;
import com.xiaozhen.common.core.utils.DateUtils;
import com.xiaozhen.common.core.utils.StringUtils;
import com.xiaozhen.common.core.utils.UserUtils;
import com.xiaozhen.system.dao.SysRoleDao;
import com.xiaozhen.system.dao.SysRoleMenuDao;
import com.xiaozhen.system.dao.SysUserRoleDao;
import com.xiaozhen.common.core.domain.system.SysUser;
import com.xiaozhen.system.service.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * HISTORY
 *
 * @author zhenweisheng
 * @date 2021/8/18 13:13
 * @description:
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysRoleDao sysRoleDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;

    @Override
    public Set<String> getRolePermission(SysUser sysUser) {
        Set<String> roles = new HashSet<String>();
        // 管理员拥有所有权限
        if (UserUtils.isAdmin(sysUser.getUserId())) {
            roles.add("admin");
        } else {
            List<String> roleKeys = sysUserRoleDao.selectRolePermissionByUserId(sysUser.getUserId());
            for (String roleKey : roleKeys) {
                if (StringUtils.isNotNull(roleKey)) {
                    roles.addAll(Arrays.asList(roleKey.trim().split(",")));
                }
            }
        }
        return roles;
    }

    @Override
    public List<SysRole> selectRoleAll() {
        return sysRoleDao.selectList(new QueryWrapper<>());
    }

    @Override
    public List<Long> selectRoleListByUserId(Long userId) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.select("role_id");
        List<SysUserRole> sysUserRoles = sysUserRoleDao.selectList(queryWrapper);
        List<Long> roleIds = sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        return roleIds;
    }

    @Override
    public Page<SysRole> selectRoleList(Page<SysRole> page, SysRoleQueryParam queryParam) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(queryParam.getRoleName())) {
            queryWrapper.like("role_name", queryParam.getRoleName());
        }
        if (StringUtils.isNotBlank(queryParam.getRoleKey())) {
            queryWrapper.like("role_key", queryParam.getRoleKey());
        }
        if (queryParam.getStatus() != null) {
            queryWrapper.eq("status", queryParam.getStatus());
        }
        if (queryParam.getParams() != null && queryParam.getParams().size() > 0) {
            Map<String, Object> params = queryParam.getParams();
            if (params.containsKey(Constants.BEGIN_TIME)) {
                LocalDateTime beginTime = DateUtils.parseStringToLocalDateTime(params.get(Constants.BEGIN_TIME).toString(), DateUtils.YMDHMS1);
                queryWrapper.ge(Constants.CREATE_TIME, beginTime);
            }
            if (params.containsKey(Constants.END_TIME)) {
                LocalDateTime endTime = DateUtils.parseStringToLocalDateTime(params.get(Constants.END_TIME).toString(), DateUtils.YMDHMS1);
                queryWrapper.le(Constants.CREATE_TIME, endTime);
            }
        }
        Page<SysRole> sysRolePage = sysRoleDao.selectPage(page, queryWrapper);
        return sysRolePage;
    }


    @Override
    public Boolean checkRoleNameUnique(SysRole sysRole) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_name", sysRole.getRoleName());
        List<SysRole> sysRoles = sysRoleDao.selectList(queryWrapper);
        if (sysRoles.size() == 0) {
            return true;
        } else if (sysRole.getRoleId() != null && sysRole.getRoleId().equals(sysRoles.get(0).getRoleId())) {
            return true;
        }
        return false;
    }

    @Override
    public Boolean checkRoleKeyUnique(SysRole sysRole) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_key", sysRole.getRoleKey());
        List<SysRole> sysRoles = sysRoleDao.selectList(queryWrapper);
        if (sysRoles.size() == 0) {
            return true;
        } else if (sysRole.getRoleId() != null && sysRole.getRoleId().equals(sysRoles.get(0).getRoleId())) {
            return true;
        }
        return false;
    }

    @Override
    public Integer insertSysRole(SysRole sysRole) {
        return sysRoleDao.insert(sysRole);
    }

    @Override
    public Integer updateSysRole(SysRole sysRole) {
        return sysRoleDao.updateById(sysRole);
    }

    @Override
    public Integer deleteRoleByIds(Long[] roleIds) {
        for (Long roleId : roleIds) {
            if (roleId == 1L) {
                throw new CustomException("不允许删除超级管理员角色");
            }
            SysRole role = selectRoleById(roleId);
            if (countUserRoleByRoleId(roleId) > 0) {
                throw new CustomException(String.format("%s已分配,不能删除", role.getRoleName()));
            }
        }
        return sysRoleDao.deleteBatchIds(Arrays.asList(roleIds));
    }

    @Override
    public SysRole selectRoleById(Long roleId) {
        return sysRoleDao.selectById(roleId);
    }

    @Override
    public Boolean checkRoleAllowed(SysRole sysRole) {
        if (StringUtils.isNotNull(sysRole.getRoleId()) && sysRole.getRoleId() == 1L) {
            return false;
        }
        return true;
    }


    @Override
    public Integer countUserRoleByRoleId(Long roleId) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleId);
        return sysUserRoleDao.selectCount(queryWrapper);
    }

    @Override
    public void assignMenuPermission(Long roleId, Long[] menuIds) {
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleId);
        sysRoleMenuDao.delete(queryWrapper);
        List<SysRoleMenu> roleMenuList = new ArrayList<>();
        if (menuIds != null && menuIds.length > 0) {
            for (Long menuId : menuIds) {
                SysRoleMenu sysRoleMenu = new SysRoleMenu();
                sysRoleMenu.setRoleId(roleId);
                sysRoleMenu.setMenuId(menuId);
                roleMenuList.add(sysRoleMenu);
            }
        }
        sysRoleMenuDao.batchRoleMenu(roleMenuList);
    }
}
